package tt.dz.order.service.rpc.client;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.List;

import javax.annotation.PostConstruct;

import org.apache.avro.Protocol;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.ipc.NettyTransceiver;
import org.apache.avro.ipc.generic.GenericRequestor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

import tt.dz.order.util.OrderAppConfig;
import tt.dz.order.util.OrderConstant.BizSystemCode;
import tt.dz.order.vo.AccountingInfo;
import tt.dz.order.vo.LoginForOperVO;
import tt.dz.order.vo.RechargeOnlineAccount;

/**
 * @Title: 订单系统调用主服务器（MS）提供的RPC服务封装的客户端类
 * @author zhoutian
 * @date 2015-11-17
 */
@Component
public class MsRpcClient {
	private static Logger log = LoggerFactory.getLogger(MsRpcClient.class);

	@Value(value = "${rpc.ms.ip}")
	private String ip;

	@Value(value = "${rpc.ms.port}")
	private int port;

	private Protocol protocol;

	public MsRpcClient() {
	}

	@PostConstruct
	public void init() {
		try {
			String filePath = this.getClass().getResource("/msAvro.json").getPath();
			log.info("msAvro.json文件路径:" + filePath);
			protocol = Protocol.parse(new File(filePath));
		} catch (IOException e) {
			log.error("初始化MsRpcClient出错", e);
		}
	}

	/**
	 * 订单系统登录，向主服务器发送登录请求
	 */
	public String loginForOper(LoginForOperVO loginForOperVO) {
		log.info("订单系统登录，向主服务器发送登录请求开始, loginForOperVO:" + loginForOperVO);
		NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("loginForOper").getRequest());
			requestData.put("loginForOperVO", JSON.toJSONStringWithDateFormat(loginForOperVO, "yyyy-MM-dd HH:mm:ss",
					SerializerFeature.WriteDateUseDateFormat));
			Object result = requestor.request("loginForOper", requestData);
			return result.toString();
		} catch (Exception e) {
			log.error("订单系统登录，向主服务器发送登录请求出错", e);
		} finally {
			if (transceiver != null)
				transceiver.close();
		}
		return null;
	}

	/**
	 * 向主服务器发送台帐信息
	 * 
	 * @param accountingInfo
	 *            台帐信息
	 */
	public String trade(List<AccountingInfo> accountingInfos) {
		log.info("向主服务器发送台帐信息开始", accountingInfos);
		NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("trade").getRequest());
			requestData.put("req", JSON.toJSONStringWithDateFormat(accountingInfos, "yyyy-MM-dd HH:mm:ss",
					SerializerFeature.WriteDateUseDateFormat));
			Object result = requestor.request("trade", requestData);
			return result.toString();
		} catch (Exception e) {
			log.error("向主服务器发送台帐信息出错", e);
		} finally {
			if (transceiver != null)
				transceiver.close();
		}
		return null;
	}

	/**
	 * 现金卡充值
	 * 
	 * @param rechargeOfflineAccount
	 * @return
	 */
	public String rechargeOnlineAccount(RechargeOnlineAccount rechargeOfflineAccount) {
		log.info("向主服务器现金卡充值开始", rechargeOfflineAccount);
		NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("trade").getRequest());
			requestData.put("req", JSON.toJSONStringWithDateFormat(rechargeOfflineAccount, "yyyy-MM-dd HH:mm:ss",
					SerializerFeature.WriteDateUseDateFormat));
			Object result = requestor.request("rechargeOnlineAccount", requestData);
			return result.toString();
		} catch (Exception e) {
			log.error("向主服务器发送现金卡充值出错", e);
		} finally {
			if (transceiver != null)
				transceiver.close();
		}
		return null;
	}

	/**
	 * 判断rpc到主服务器是否执行成功<br>
	 * 用户数据处理，<br>
	 * 不适合数据查询
	 * 
	 * @param result
	 * @return
	 */
	public boolean isRpcOperationSuccess(String result) {
		if (result == null) {
			return false;
		}
		JSONObject resultJSON = JSON.parseObject(result);
		String isSuccess = resultJSON.getString("isSuccess");
		return isSuccess != null && isSuccess.equals("1");
	}

	/**
	 * 获取短信验证码
	 * 
	 * @return
	 */
	public String getCheckCode(String mobileNo) {
		log.info("订单系统请求发送验证码:" + mobileNo);
		NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("getCheckCode").getRequest());
			JSONObject jsonObject=new JSONObject();
			jsonObject.put("merchantCode", OrderAppConfig.GET().getMerchantCode());
			jsonObject.put("mobileNo", mobileNo);
			requestData.put("req", jsonObject.toJSONString());
			Object result = requestor.request("getCheckCode", requestData);
			return result.toString();
		} catch (Exception e) {
			log.error("订单系统请求发送验证码", e);
		} finally {
			if (transceiver != null)
				transceiver.close();
		}
		return null;
	}

	/**
	 * 获取短信验证码
	 * 
	 * @return
	 */
	public String verifyCheckCode(String mobileNo, String checkCode) {
		log.info("订单系统请求校验验证码:" + mobileNo);
		NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(
					protocol.getMessages().get("verifyCheckCode").getRequest());
			JSONObject jsonObject=new JSONObject();
			jsonObject.put("checkCode", checkCode);
			jsonObject.put("mobileNo", mobileNo);
			requestData.put("req", jsonObject.toJSONString());
			Object result = requestor.request("verifyCheckCode", requestData);
			return result.toString();
		} catch (Exception e) {
			log.error("订单系统请求校验验证码", e);
		} finally {
			if (transceiver != null)
				transceiver.close();
		}
		return null;
	}

	/**
	 * 根据userId,或者昵称以及手机号查询相关操作人员的基本信息,(不包括角色信息)
	 * 
	 * @param queryValue
	 * @param queryType
	 *            查询的类别, 1:managerId,操作人员id; 2:name,用户名;
	 *            3:mobile,手机号,4:nickName昵称
	 * @return
	 */
	public String queryOperUserBaseInfo(String queryValue, String queryType) {
		log.info("查询相关操作人员:" + queryValue);
		NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(
					protocol.getMessages().get("queryOperUserBaseInfo").getRequest());
			JSONObject jsonObject=new JSONObject();
			jsonObject.put("queryValue", queryValue);
			jsonObject.put("queryType", queryType);
			jsonObject.put("sysCode", BizSystemCode.OrderServer.value());
			requestData.put("req", jsonObject.toJSONString());
			Object result = requestor.request("queryOperUserBaseInfo", requestData);
			return result.toString();
		} catch (Exception e) {
			log.error("订单系统请求校验验证码", e);
		} finally {
			if (transceiver != null)
				transceiver.close();
		}
		return null;
	}
}
